//
//  Rectangle.h
//  Chart
//
//  Created by CaoJun on 13-5-22.
//
//

#ifndef __Chart__Rectangle__
#define __Chart__Rectangle__

#include "YTXChartTools.h"
#include "YTXConfig.h"
#include "Metal.h"

#include "YTXGeometry.h"

#include <math.h>

namespace ytx {
    typedef YTXConfig Config;

    struct RectangleOption {
        float paddingTop;
        float paddingRight;
        float paddingBottom;
        float paddingLeft;
        float rounded;
        Rect row;
        Rect column;
        RectangleOption(): paddingTop(Config::getInstance()->style.rectPaddingTop), paddingRight(Config::getInstance()->style.rectPaddingRight), paddingLeft(Config::getInstance()->style.rectPaddingLeft), paddingBottom(Config::getInstance()->style.size+3),rounded(10){

        };
        RectangleOption(Rect row, Rect column) : row(row),column(column) {

        };

        RectangleOption(Rect row, Rect column, float paddingTop, float paddingRight, float paddingBottom, float paddingLeft, float rounded) : row(row), column(column), paddingTop(paddingTop), paddingRight(paddingRight), paddingBottom(paddingBottom), paddingLeft(paddingLeft), rounded(rounded)
        {
        };

        RectangleOption(const RectangleOption & rect): row(rect.row), column(rect.column), paddingTop(rect.paddingTop), paddingRight(rect.paddingRight), paddingBottom(rect.paddingBottom), paddingLeft(rect.paddingLeft), rounded(rect.rounded){
        };

    };

    namespace SizeType {
        enum SizeType {
            small, middle, big
        };
    }

    class Rectangle {
    public:
        Rectangle();
        Rectangle(YTXSize* size, RectangleOption rect);
        Rectangle(const YTXSize & size);
        Rectangle(int width, int height, RectangleOption rect);
        Rectangle(int width, int height);
        virtual ~Rectangle();

        void resize(YTXSize* size, RectangleOption rect);
        void resize(const YTXSize & size);
        void resize(int width, int height);
        void resize(int width, int height, RectangleOption rect);

        void changePaddingBottom(float bottomPadding);
        void changePaddingTop(float bottomTop);

        SizeType::SizeType getWidthType() const;
        SizeType::SizeType getHeightType() const;

        void resetRowAndColumn(Rect row, Rect column);

        void resetRowAndColumn(int row, int column);

        void setRectanglePara(double max, double min);

        double sideTextAccuracy(double v, double sideTextAccuracy) const
        {
            return  v + v * 2 * sideTextAccuracy / getRectHeight();
        }

        double adjustValueByDiff(double v, double retentionSize) const
        {
            return v * retentionSize / CanvasHeight;
        }

        void setColumnByRectHeight(int small, int middle, int big);

        bool sizeEqual(Rectangle & rect) const{
            return rect.getRow() == Row && rect.getColumn() == Column && rect.getBeginX() == BeginX && rect.getBeginY() == BeginY && rect.getCanvasWidth() == CanvasWidth && rect.getCanvasHeight() == CanvasHeight;
        }

        int getColumn() const {
            return Column;
        }

        void setColumn(int column)  {
            Column = column;
            DistanceY = RectHeight / Column;
        }

        int getRow() const {
            return Row;
        }

        void setRow(int row){
            Row = row;
            DistanceX = RectWidth / Row;
        }

        float getCanvasWidth() const {
            return CanvasWidth;
        }

        float getCanvasHeight() const {
            return CanvasHeight;
        }

        float getRectWidth() const {
            return RectWidth;
        }

        float getRectHeight() const {
            return RectHeight;
        }

        float getBeginX() const {
            return BeginX;
        }

        float getBeginY() const {
            return BeginY;
        }

        float getCenterY() const {
            return (EndY-BeginY)*0.5;
        }

        float getCenterX() const {
            return (EndX-BeginX)*0.5;
        }

        float getEndX() const {
            return EndX;
        }

        float getEndY() const {
            return EndY;
        }

        float getZoomX() const {
            return ZoomX;
        }

        void setZoomX(int num) {
            if (RectWidth != 0) {
                ZoomX = RectWidth / num;
            }
        }

        float getZoomY() const {
            return ZoomY;
        }

        void setZoomY(double maxValue, double minValue) {
            ZoomY = (float) ((maxValue - minValue) / RectHeight);
        }

        double getMax() const {
            return Max;
        }

        void setMax(double max) {
            Max = max;
        }

        double getMin() const {
            return Min;
        }

        void setMin(double min) {
            Min = min;
        }

        float getDistanceX() const {
            return DistanceX;
        }

        void setDistanceX(float distanceX) {
            DistanceX = distanceX;
        }

        float getDistanceY() const {
            return DistanceY;
        }

        void setDistanceY(float distanceY) {
            DistanceY = distanceY;
        }

        float getPaddingTop() const {
            return paddingTop;
        }

        float getPaddingRight() const {
            return paddingRight;
        }

        float getPaddingBottom() const {
            return paddingBottom;
        }

        float getPaddingLeft() const {
            return paddingLeft;
        }

        RectangleOption getRectangleOption() const {
            return defaultSetting;
        }

        bool inRect(float left, float top, float x, float y);

        float getPxY(double value) const;

        double getValueY(float px) const;

        int getViewIndexByPX(float px) const;

        float getViewPxByViewIndex(int dx) const;
        
        float getViewPxByViewIndexWithoutModify(int dx) const;

        int getDiffBetweenTwoPx(int x1, int x2);

        int getDiffBetweenTwoPx(int x);

        void setPreViewPx(int x);

        YTXPoint getInfoPosition(float x, float left, int width) const;

    private:

        float CanvasWidth;
        float CanvasHeight;
        float paddingTop;
        float paddingRight;
        float paddingBottom;
        float paddingLeft;
        float rounded;
        RectangleOption defaultSetting;
        float RectWidth;
        float RectHeight;
        float BeginX;
        float BeginY;
        float EndX;
        float EndY;
        int Row;
        int Column;
        float DistanceX;
        float DistanceY;
        float ZoomX;
        float ZoomY;
        double Max;
        double Min;

    };

}
#endif /* defined(__Chart__Rectangle__) */

